<?php

namespace addons\mental\controller;

use addons\mental\model\Order as orderModel;
use addons\mental\model\TestMain;
use addons\mental\model\Testlog;
use app\admin\model\Exchangecode;
use fast\Http;
use think\Db;
use think\Exception;
use think\Log;

class Order extends Base
{
    protected $noNeedLogin = ['tt_pay', 'create', 'pay', 'getinvitationcode', 'detail'];

    /**
     * Undocumented function
     * 创建订单
     * @return void
     */
    public function create()
    {
        $main_id = $this->request->param('main_id');
        $type = $this->request->param('type/d');
        $test_id = $this->request->param('test_id/d');
        $extensionId = $this->request->param('fxId');
        $extensionId = $extensionId ? $extensionId : 0;
        $pid = $this->request->param('pid');
        $pid = $pid ? $pid : 0;
        $test_num = $this->request->param('test_num');
        $test_num = $test_num ?? 0;

        $age = $this->request->param('age');
        $gender = $this->request->param('gender');
        $age = $age ?? '用户未填写';
        $gender = $gender ?? '用户未填写';

        if (!$main_id) {
            $this->error(__('Invalid parameters'));
        }
        $testMain = new TestMain();
        $test = $testMain->where('switch', 1)->where('id', $main_id)->find();
        if (empty($test)) {
            $this->error(__('No results were found'));
        }
        $uid = $this->auth->id ?? 0;

        if (!$type) {
            //免费的或付费查看结果的直接到测试
            if ($test->pay_mode != 2) {
                $testlog = Testlog::create(['user_id' => $uid, 'main_id' => $main_id, 'pid' => $pid, 'age' => $age, 'gender' => $gender]);
                if ($testlog) {
                    \addons\mental\model\TestMainStatistics::setIncNum($main_id, 1, $extensionId);
                    $this->success(__('Operation completed'), ['test_id' => $testlog->id]);
                }
                $this->error(__('Operation failed'));
            }
        } else {
            if ($type !== 6) {
                if (!$test_id) {
                    $this->error('缺少测试参数！');
                }
            }
        }


        try {

            if ($type == 1) {
                $price = $test->price;
                $isOrder = \think\Db::name('mental_order')->where(['type' => 2, 'main_id' => $main_id, 'test_id' => $test_id, 'status' => 'paid'])->find();

                if ($isOrder) {
                    $price = $test->price - $test->price1;
                    $type = 5;
                }
            } elseif ($type == 2) {
                $price = $test->price1;
            } elseif ($type == 3) {
                $price = $test->price + $test->price2;
            } elseif ($type == 4) {
                $price = $test->price3;
            } elseif ($type == 6) {
                if ($test_num < 5) {
                    $this->error('购买数量必须大于5');
                }

                if (!$this->auth->id) {
                    $this->error('请登录后购买');
                }
                $price = $test->team_price * $test_num;
            } else {
//                $this->error('参数错误');
                $price = $test->price;
            }


            if ($price < 0) {
                $this->error('网络错误');
            }
//            $testlog = Testlog::create(['user_id' => $uid, 'main_id' => $main_id, 'pid' => $pid, 'age' => $age, 'gender' => $gender]);
            $order_id = orderModel::submitOrder($price, $uid, $main_id, $type, $test_id, $extensionId, $test_num);
            \addons\mental\model\TestMainStatistics::setIncNum($main_id, 5, $extensionId);
            $this->success(__('Operation completed'), ['order_id' => $order_id/*,'test_id'=>$testlog->id*/], 2);
        } catch (Exception $e) {
            $this->error($e->getMessage());
        }
    }

    /**
     * Undocumented function
     * 订单信息
     *(addons/mental/order/detail)
     * @return void
     * @param int $order_id 订单号
     */
    public function detail()
    {
        // var_dump(111111);die;
        $order_id = $this->request->param('order_id');

        if (!$order_id) {
            $this->error(__('Invalid parameters'));
        }
        $orderModel = new orderModel();
        $order = $orderModel
            ->field('order_id,amount,test_id,status,type,main_id')
            // ->where('user_id', $this->auth->id)
            ->where('order_id', $order_id)
            ->find();
        if (empty($order)) {
            $this->error(__('No results were found'));
        }
        $this->success(__('Operation completed'), $order);
    }

    /**
     * Undocumented function
     * 支付(addons/mental/order/pay)
     * @param int $order_id 订单id
     * @param string $paytype 支付方式:wechat=微信,alipay=支付宝
     * @param string $method web、wap、app、scan、pos、mp，miniapp
     * @param string $url 公众号授权回调url 或 h5支付回调url
     * @return void
     */
    public function pay()
    {
        $order_id = $this->request->param('order_id');
        $paytype = $this->request->param('paytype', 'wechat');
        $method = $this->request->param('method', 'miniapp');
        $attach = $this->request->param('attach', 'mental');//订单类型 mental=评测 video=视频 consult=沟通
        $url = $this->request->param('url', '', 'trim'); //公众号授权回调url 或 h5支付回调url
        // $method = 'mp';
        Log::info('支付传参');
        Log::info($this->request->param());
        if (!$order_id) {
            $this->error(__('Invalid parameters'));
        }
        $user = $this->auth->getUserinfo();
        $orderModel = new orderModel();
        $order = $orderModel
            ->where('order_id', $order_id)
            ->where('user_id', $this->auth->id)
            ->where('status', 'created')
            ->find();

        if (empty($order)) {
            $this->error(__('No results were found'));
        }
        $openid = \app\admin\model\User::where(['id'=>$this->auth->id])->value('openid');
//        halt($openid);
        try {
//            $attach = 'mental';
            $result = orderModel::pay($this->auth->id, $order_id, $order->amount, $paytype, $method, $url, $openid, $attach);
            if (!is_array($result)) {
                $this->success(__('Operation completed'), $result);
            } else {
                $this->error(__('Operation failed'), $result['data'], 2); //判断公众号授权
            }
        } catch (Exception $e) {
            $this->error($e->getMessage());
        }
    }

    /**
     * Undocumented function
     * 头条支付
     * @return void
     */
    public function tt_pay()
    {
        $order_id = $this->request->param('order_id');

        if (!$order_id) {
            $this->error(__('Invalid parameters'));
        }
        $orderModel = new orderModel();
        $order = $orderModel
            ->where('order_id', $order_id)
            ->where('user_id', $this->auth->id)
            ->where('status', 'created')
            ->find();
        if (empty($order)) {
            $this->error(__('No results were found'));
        }
        try {
            $config = get_addon_config('mental');
            //担保支付
            if ($config['tt_pay_type'] == 1) {
                $this->success(__('Operation completed'), $this->tt_pay2($order, $config));
            } else {
                $this->success(__('Operation completed'), $this->tt_pay1($order, $config));
            }
        } catch (Exception $e) {
            $this->error($e->getMessage());
        }
    }

    /**
     * @ DateTime 2022-02-26
     * @ 收银台支付
     * @return void
     */
    protected function tt_pay1($order,  $config)
    {
        $ttUser = (new \addons\mental\model\WxUser())->where('type', 3)->where('user_id', $this->auth->id)->find();
        if (!$ttUser) {
            $this->error('授权数据不存在！');
        }
        $wx_notify_url = $this->request->root(true) . '/addons/mental/callback/epay/type/return/paytype/wechat';
        $al_notify_url = $this->request->root(true) . '/addons/mental/callback/epay/type/return/paytype/alipay';
        $wx_obj = orderModel::pay($this->auth->id, $order->order_id, $order->amount, 'wechat', 'wap', $wx_notify_url);
        $al_obj = orderModel::pay($this->auth->id, $order->order_id, $order->amount, 'alipay', 'app', $al_notify_url);

        $orderInfo = [
            "app_id"       => $config['tt_pay_appid'],
            "sign_type"    => "MD5",
            "out_order_no" => $order->order_id,
            "merchant_id"  => $config['tt_merchant_id'],
            "timestamp"    => (string) time(),
            "product_code" => "pay",
            "payment_type" => "direct",
            "total_amount" => $order->amount * 100,
            "trade_type"   => "H5",
            "uid"          => $ttUser['openid'],
            "version"      => "2.0",
            "currency"     => "CNY",
            "subject"      => "心理测试",
            "body"         => "支付",
            "trade_time"   => (string) $order['updatetime'],
            "valid_time"   => "7200",
            "notify_url"   => $wx_notify_url,
            "wx_url"       => $wx_obj->getTargetUrl(),
            "wx_type"      => "MWEB",
            "alipay_url"   => (string)$al_obj
        ];

        $risk_info         = [
            'ip' => $this->request->ip(),
        ];
        $stringToBeSigned = $this->getSignContent($orderInfo, "UTF-8", $config['tt_pay_secret']);
        $sign             = md5($stringToBeSigned);
        $orderInfo['risk_info'] = json_encode($risk_info);
        $orderInfo['sign']      = $sign;
        return $orderInfo;
    }
    /**
     * @ DateTime 2022-02-26
     * @ 头条担保支付
     * @return void
     */
    protected function tt_pay2($order, $config)
    {
        $url = 'https://developer.toutiao.com/api/apps/ecpay/v1/create_order';
        $orderInfo = [
            "app_id" => $config['tt_pay_appid'],
            "out_order_no" => $order['order_id'],
            "total_amount" => $order['amount'] * 100,
            "subject" => "心理测试",
            "body" => "心理测试",
            "valid_time" => 7200,
            "cp_extra" => "",
            "notify_url" => $this->request->root(true) . '/addons/mental/callback/ttPay',
            "disable_msg" => 0,
            "msg_page" => "pages/member/mytest"
        ];
        $sign             = $this->getPaySign($orderInfo, $config['tt_pay_salt']);
        $orderInfo['sign']      = $sign;
        $Http = new Http();
        $result = $Http->post($url, json_encode($orderInfo), ['Content-Type: application/json']);
        $result = (array)json_decode($result, true);
        if ($result['err_no'] == 0) {
            return $result['data'];
        }
        throw new Exception($result['err_tips']);
    }

    /**
     * @ DateTime 2022-02-26
     * @ 担保交易签名
     * @param [type] $map
     * @param [type] $tt_pay_salt
     * @return void
     */
    protected function getPaySign($map, $tt_pay_salt)
    {
        $rList = array();
        foreach ($map as $k => $v) {
            if ($k == "other_settle_params" || $k == "app_id" || $k == "sign" || $k == "thirdparty_id")
                continue;
            $value = trim(strval($v));
            $len = strlen($value);
            if ($len > 1 && substr($value, 0, 1) == "\"" && substr($value, $len, $len - 1) == "\"")
                $value = substr($value, 1, $len - 1);
            $value = trim($value);
            if ($value == "" || $value == "null")
                continue;
            array_push($rList, $value);
        }
        array_push($rList, $tt_pay_salt);
        sort($rList, 2);
        return md5(implode('&', $rList));
    }

    /**
     * 签名处理
     * @param $params
     * @param $charset
     * @return string
     */
    public function getSignContent($params, $charset = "", $app_secret)
    {
        ksort($params);
        $stringToBeSigned = "";
        $i                = 0;
        foreach ($params as $k => $v) {
            if (false === $this->checkEmpty($v) && "@" != substr($v, 0, 1)) {
                // 转换成目标字符集
                $v = $this->characet($v, $charset);
                if ($i == 0) {
                    $stringToBeSigned .= "$k" . "=" . "$v";
                } else {
                    $stringToBeSigned .= "&" . "$k" . "=" . "$v";
                }
                $i++;
            }
        }
        $stringToBeSigned = $stringToBeSigned . $app_secret;
        unset($k, $v);
        return $stringToBeSigned;
    }

    /**
     * 校验$value是否非空
     * @param $value
     * @return  boolean;
     *  if not set ,return true;
     *  if is null , return true;
     **/
    public function checkEmpty($value)
    {
        if (!isset($value)) {
            return true;
        }

        if ($value === null) {
            return true;
        }

        if (trim($value) === "") {
            return true;
        }

        return false;
    }

    /**
     * 转换字符集编码
     * @param $data
     * @param $targetCharset
     * @return string
     */
    public function characet($data)
    {
        if (!empty($data)) {
            $data = mb_convert_encoding($data, "UTF-8", "auto");
        }
        return $data;
    }

    /**
     * 获取邀请码(addons/mental/order/getinvitationcode)
     * @param int $order_id
     */
    public function getinvitationcode()
    {
        $order_id = $this->request->param('order_id');

        $invitation_code = \think\Db::name('mental_order')->where('order_id', $order_id)->value('invitation_code');
        if ($invitation_code) {
            $isStatus = \think\Db::name('mental_order')->where('order_id', $order_id)->value('status');
            if ($isStatus == 'paid') {
                $this->success('成功', $invitation_code);
            } else {
                $this->error('订单未支付');
            }
        } else {
            $this->error('订单不存在');
        }
    }

    /*
     * 测试使用兑换码代替支付
     * */
    public function exchange_code()
    {
        $code = $this->request->param('code', '');
        $order_id = $this->request->param('order_id');
        if (!$order_id || !$code) {
            $this->error(__('Invalid parameters'));
        }
        $orderModel = new orderModel();
        $order = $orderModel
            ->where('order_id', $order_id)
             ->where('user_id', $this->auth->id)
            ->where('status', 'created')
            ->find();

        if (empty($order)) {
            $this->error(__('No results were found'));
        }
        $code_exist = Exchangecode::where(['code'=>$code,'status'=>0,'type'=>1])->find();
        if (!$code_exist){
            $this->error('兑换码不存在');
        }

        // 启动事务
        Db::startTrans();
        try {
            //更新兑换卡
            $code_exist->test_mainid = $order['main_id'];
            $code_exist->user_id = $this->auth->id;
            $code_exist->order_id = $order_id;
            $code_exist->status = 1;
            $code_exist->save();

            //更新订单
            $order->status = 'paid';
            $order->paytime = time();
            $order->paytype = 'code';
            $order->save();
            // 提交事务
            Db::commit();
        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
            Log::info("兑换测试失败:order_id=$order_id;errog=".$e->getMessage());
            $this->error('兑换失败');
        }

        $this->success('兑换成功');

    }
}
